<?php
/**
*	Form
*
*	Класс для работы с формами
*	@author Денис Орлов, denis_orlov@rambler.ru
*	@version 1.0
*/
class Form extends CoreModule{
	/**
	* массивы для сбора значений и ошибок посланных полей форм
	*/
	static $errors = array(), $values = array();
	
	/**
	*	value
	*
	*	Получение или установка значения статического массива $values 
	*	@param string $group - имя группы значений, подмассив
	*	@param string $name - ключ записи
	*	@param string $_value - значение или null
	*/
	static function value( $group, $name, $_value=null ) {
		if(!isset(self::$values[$group])) self::$values[$group] = array();
		return self::_get_set( self::$values[$group], $name, $_value );	
	}
	/**
	*	error
	*
	*	Получение или установка значения статического массива $errors 
	*	@param string $group - имя группы значений, подмассив
	*	@param string $name - ключ записи
	*	@param string $_value - значение или null
	*/
	static function error( $group, $name, $_value=null  ) {
		if(!isset(self::$errors[$group])) self::$errors[$group] = array();
		return self::_get_set( self::$errors[$group], $name, $_value );	
	}
	/**
	* 	errorsAll
	*
	*	Возврат массива записей ошибок по группе или всего
	*	@return array
	*/
	static function errorsAll( $group=null  ) {
		if(is_null($group)) return self::$errors;
		if(!isset(self::$errors[$group])) return array();
		return self::$errors[$group];
	}
	/**
	* 	valuesAll
	*
	*	Возврат массива значений value по группе или всего
	*	@return array
	*/
	static function valuesAll( $group=null  ) {
		if(is_null($group)) return self::$values;
		if(!isset(self::$values[$group])) return array();
		return self::$values[$group];
	}
	
	/**
	*	outMessages
	*
	*	вывод сообщений на форму, используя  массив $self::errors
	*	@param	string $template_file  - абсолютный путь к шаблону
	*/	
	static function outErrors( $group=null, $template_file=null ) {
		if(is_null($template_file)) $template_file = _DOCUMENT_ROOT.TMPL_DEFAULT.'/'.'form_errors.php';
		if( file_exists($template_file) && is_file($template_file) ){
			$arOut = self::errorsAll( $group );
			return self::includeInOb( $template_file, $arOut );		
		}else 
			throw new Exception( __METHOD__.': '.Lang::get( '{FILE}_DOESNT_EXISTS', array('{FILE}'=>$template_file) ) );
	}

	
	/**
	*	checkFields
	*
	*	Проверка обязательных ($mandatory) и необязательных ($noMandatory) полей 
	*	в массивах типа:
	*<code>
	*$mandatory = array(
	*	'email'=>array('/^\w+([\.\w]+)*\w@\w((\.\w)*\w+)*\.\w{2,3}$/', Lang::get('NO_VALID_EMAIL')),
	*	'password'=>array('/^[\w\d]{6,30}$/u', Lang::get('PASSWORD_RULES')),
	*);
	*</code>
	*	где первый элемент regexp , второй - текст для вывода ошибки
	*	необязательные проверяются только если присутствуют в запросе $_REQUEST
	*	@param	array $mandatory обязательные
	*	@param	array $noMandatory необязательные
	*	@return array $errors массив полей ошибок
	*/
	static function checkFields( $mandatory=null, $noMandatory=null ){
		/* массив полей ошибок */
		$errors = array();
		
		/* проверка  */  
		if(is_array($mandatory))			
		foreach($mandatory as $name=>$arr)
		if(isset($_REQUEST[$name]) ){
			if(is_array($arr) && !preg_match($arr[0], $_REQUEST[$name]) ){
				$errors[$name] = $arr[1];
			}else
			if(strlen($_REQUEST[$name])<1) 
				$errors[$name] = 'Обязательное поле';

		}
		
		/* проверка  необязательный полей */ 
		if(is_array($noMandatory))	
		foreach($noMandatory as $name=>$arr)
		if(isset($_REQUEST[$name]) ){
			if(strlen($_REQUEST[$name])>0 && is_array($arr) && !preg_match($arr[0], $_REQUEST[$name]) ){
				$errors[$name] = $arr[1];
			}
		}
		
		return $errors;

	}
	
	/**
	*	Предотвращение повторной отправки формы, 
	*	сравнивает ключи "posttime" массивов $_REQUEST и $_SESSION
	*	Форма должна иметь поле:
	*	<code>
	*	<input type="hidden" name="posttime" value="<?php echo time();?>" />
	*	</code>	
	*		
	*	Пример обработчика:	
	*	<code>
	*	if( Form::isRepeatedSubmit()) $arResult['ERRORS'][] = $MESS['PREVENT_REPEATED_SUBMIT']; 
	*	else{
	*		$_SESSION['posttime']=$_REQUEST['posttime'];//rewrite key
	*		// ...
	*	}	
	*	</code>		
	*/
	static function  isRepeatedSubmit() {
		if( !empty($_SESSION['posttime']) && !empty($_REQUEST['posttime']) && $_SESSION['posttime']==$_REQUEST['posttime'] ) 
		return true;/* повторная отправка данных формы */
		else return false;
	}
	
	/**
	*	createFormFromTable
	*
	*	Создание  формы по таблице, используя комментарии полей как заголовки,
	*	форма создается по шаблону, используя массив вывода $arOut	
	*	@param	string $table имя таблицы
	*	@param	string $template_path  - абсолютный путь к шаблону
	*	@return string  - форма и textarea с кодом
	*/
	static function createFormFromTable( $table, $template_path ){
		$arOut = array(); $inputs = array(); $input='';
		$sql='SELECT '.
		'COLUMN_NAME,COLUMN_DEFAULT,IS_NULLABLE,DATA_TYPE,COLUMN_TYPE,COLUMN_COMMENT '.
		'FROM information_schema.columns '.
		'WHERE table_name = \''.$table.'\' AND table_schema = \''.DB_NAME.'\'';
		$cols=exec_sql2array( $sql ); //myPrint($cols, '$cols'); 
		foreach( $cols as $col){
			if( empty($col['COLUMN_COMMENT']) ) continue;	
			$inputs[] = array('title'=> $col['COLUMN_COMMENT'], 'data_type'=>$col['DATA_TYPE'], 'name'=>$col['COLUMN_NAME'], 'is_nullable'=>$col['IS_NULLABLE'], 'column_type'=>$col['COLUMN_TYPE']  );
		}
		$arOut['inputs'] =$inputs;
		$arOut['table'] = $table;
		$arOut['form_name'] = $table.'_form';
		
		$form = self::includeInOb( $template_path, $arOut);
		return '~VIEW:<br/>'.$form.'CODE:<br/><textarea cols="80" rows="20">'.htmlspecialchars($form).'</textarea>';
	}
	
	static function createSelectOptions( array $options, $selected=null ){
		$res = ''; 
		foreach($options as $key=>$value){
			$_selected='';
			if(is_array($selected)){
				if(in_array( strval($key), $selected) || in_array( $value, $selected) )
					$_selected = 'selected="selected"';
			}else
			if(is_string($selected)){
				if(strval($key)==strval($selected) || $selected==$value) 
					$_selected = 'selected="selected"';
			}
			
			$res.='<option value="'.$key.'" '.$_selected.' >'.$value.'</option>';
		}
		return $res;
	}
	
	static function getEnumArray( $table_name, $column_name ){
		$resultAr = array();
		$sql= 'SELECT COLUMN_TYPE FROM information_schema.columns '.
		'WHERE `table_schema` = "'.DB_NAME.'" AND `table_name` = "'.$table_name.'" AND `COLUMN_NAME` = "'.$column_name.'"';
		$cols=exec_sql2array( $sql ); //myPrint($cols, '$cols'); 
		if(count($cols)>0){
			preg_match_all("/'(.*?)'/i", $cols[0]['COLUMN_TYPE'], $optionAr);
			if(count($optionAr)>0 )
				foreach($optionAr[1] as $val) $resultAr[$val]=$val; //if(count($optionAr)>0 ) $resultAr = $optionAr[1];
		}
		
		return $resultAr;
	}
	
	/**
	* Проверка и возврат значение из $_REQUEST для заполнения переданных полей формы
	*/
	static function requested( $name, $default=null ){
		return isset( $_REQUEST, $_REQUEST[$name] ) ? $_REQUEST[$name] : $default ;
	}
	
}
?>